package com.gitee.qdbp.general.common.biz.sms.service;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.JSONLexerBase;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.api.sms.model.ISmsTemplate;
import com.gitee.qdbp.general.common.error.GeneralErrorCode;
import com.gitee.qdbp.tools.codec.DigestTools;
import com.gitee.qdbp.tools.http.HttpException;
import com.gitee.qdbp.tools.http.HttpTools;
import com.gitee.qdbp.tools.http.RemoteServiceException;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 互亿无线短信接口<br>
 * https://user.ihuyi.com/login.html<br>
 * http://www.ihuyi.com/api/sms.html<br>
 *
 * @author zhaohuihua
 * @version 180831
 */
public class IhuyiSmsService extends BaseSmsService {

    private static final Logger log = LoggerFactory.getLogger(IhuyiSmsService.class);

    public IhuyiSmsService() {
        this.properties = "settings/sms/sms.ihuyi.txt";
    }

    @Override
    @PostConstruct
    public void init() {
        super.init();
    }

    @Override
    public String send(String phone, ISmsTemplate template, Object... args) throws ServiceException {

        utils.check(phone, template.name());

        String msg = "Failed to send Short Message. phone:{}, template:{}.";

        String[] placeholder = config.getArray("sms.content." + template + ".params", false);
        if (placeholder == null) {
            placeholder = new String[0];
        }
        if (args.length < placeholder.length) {
            log.error(msg + " The number of parameters is not enough.");
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < placeholder.length && i < args.length; i++) {
            map.put(placeholder[i], String.valueOf(args[i]));
        }

        String url = config.getString("sms.service.url") + config.getString("sms.submit.method");
        String account = config.getString("auth.account");
        String password = config.getString("auth.password");

        String signature = config.getString("sms.signature", false);

        String content = config.getString("sms.content." + template);
        if (VerifyTools.isBlank(content)) {
            log.error(msg + " sms template not found.", phone, template);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        String formatted = (signature == null ? "" : signature) + StringTools.format(content, map);

        Map<String, Object> params = new HashMap<>();
        params.put("account", account);
        params.put("password", DigestTools.md5(password));
        params.put("mobile", phone);
        params.put("content", formatted);
        params.put("format", "json");

        String result;
        try {
            String temp = HttpTools.form.post(url, params);
            char[] chars = temp.toCharArray();
            result = JSONLexerBase.readString(chars, chars.length); // unicode字符转码
        } catch (HttpException e) {
            log.error(msg + "\n\t{}\n\t{}", phone, template, url, formatted, e);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        // { code:"2", message:"提交成功", smsid:"xxx" }
        JSONObject json;
        try {
            json = JSON.parseObject(result);
        } catch (Exception e) {
            log.error(msg + " result format error:[{}]\n\t{}\n\t{}", phone, template, result, url, formatted, e);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        String code = json.getString("code");
        if (config.getString("resultcode.success").equals(code)) {
            String txt = "Send Short Message success. phone:{}, template:{}.";
            log.trace(txt + " result: {}\n\tcontent: {}", phone, template, result, formatted);
            return json.getString("smsid");
        } else {
            String desc = json.getString("msg");
            log.error(msg + " result:{}[{}]\n\t{}\n\t{}", phone, template, desc, result, url, formatted);
            if (VerifyTools.isBlank(desc)) {
                desc = "UnknownException";
            }
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR, new RemoteServiceException(result, desc));
        }

    }

    @Override
    public Double balances() throws ServiceException {
        String msg = "Failed to get sms balances. ";

        String url = config.getString("sms.service.url") + config.getString("sms.balances.method");
        String account = config.getString("auth.account");
        String password = config.getString("auth.password");

        Map<String, Object> params = new HashMap<>();
        params.put("account", account);
        params.put("password", DigestTools.md5(password));
        params.put("format", "json");

        String result;
        try {
            // {"code":2,"msg":"\u67e5\u8be2\u6210\u529f","num":8}
            String temp = HttpTools.form.post(url, params);
            char[] chars = temp.toCharArray();
            // {"code":2,"msg":"查询成功","num":8}
            result = JSONLexerBase.readString(chars, chars.length); // unicode字符转码
        } catch (HttpException e) {
            log.error(msg + "\n\t{}", url, e);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        // { code:"2", message:"查询成功", num:8 }
        JSONObject json;
        try {
            json = JSON.parseObject(result);
        } catch (Exception e) {
            log.error(msg + " result format error:[{}]\n\t{}", result, url, e);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR);
        }

        String code = json.getString("code");
        if (config.getString("resultcode.success").equals(code)) {
            log.trace("Query sms balances success. result: {}", result);
            return json.getDouble("num");
        } else {
            String desc = json.getString("msg");
            log.error(msg + " result:{}[{}]\n\t{}", desc, result, url);
            if (VerifyTools.isBlank(desc)) {
                desc = "UnknownException";
            }
            throw new ServiceException(GeneralErrorCode.SMS_SEND_ERROR, new RemoteServiceException(result, desc));
        }
    }

}
